home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
gfx
/
show
/
GS510_data.lha
/
ghostscript
/
5.10
/
gs_setpd.ps
< prev
next >
Wrap
Text File
|
1997-12-28
|
21KB
|
668 lines
% Copyright (C) 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
% or distributor accepts any responsibility for the consequences of using it,
% or for whether it serves any particular purpose or works at all, unless he
% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
% License (the "License") for full details.
%
% Every copy of Aladdin Ghostscript must include a copy of the License,
% normally in a plain ASCII text file named PUBLIC. The License grants you
% the right to copy, modify and redistribute Aladdin Ghostscript, but only
% under certain conditions described in the License. Among other things, the
% License requires that the copyright notice and this notice be preserved on
% all copies.
% The current implementation of setpagedevice has the following limitations:
% - It doesn't attempt to "interact with the user" for Policy = 2.
languagelevel 1 .setlanguagelevel
level2dict begin
% ---------------- Redefinitions ---------------- %
% Redefine .beginpage and .endpage so that they call BeginPage and
% EndPage respectively if appropriate.
% We have to guard against the BeginPage procedure not popping its operand.
% This is really stupid, but the Genoa CET does it.
/.beginpage % - .beginpage -
{ .currentshowpagecount
{ .currentpagedevice pop /BeginPage .knownget
{ % Stack: ... pagecount proc
count 2 .execn
% Stack: ... ..???.. oldcount
count 1 add exch sub { pop } repeat
}
{ pop
}
ifelse
}
if
} bind odef
% Guard similarly against EndPage not popping its operand.
/.endpage % <reason> .endpage <print_bool>
{ .currentshowpagecount
{ 1 index .currentpagedevice pop /EndPage .knownget
{ % Stack: ... reason pagecount reason proc
count 2 .execn
% Stack: ... ..???.. print oldcount
count 2 add exch sub { exch pop } repeat
}
{ pop pop 2 ne
}
ifelse
}
{ 2 ne
}
ifelse
} bind odef
% Define interpreter callouts for handling gstate-saving operators,
% to make sure that they create a page device dictionary for use by
% the corresponding gstate-restoring operator.
% We'd really like to avoid the cost of doing this, but we don't see how.
% The names %gsavepagedevice, %savepagedevice, %gstatepagedevice,
% %copygstatepagedevice, and %currentgstatepagedevice are known to the
% interpreter.
(%gsavepagedevice) cvn
{ currentpagedevice pop gsave
} bind def
(%savepagedevice) cvn
{ currentpagedevice pop save
} bind def
(%gstatepagedevice) cvn
{ currentpagedevice pop gstate
} bind def
(%copygstatepagedevice) cvn
{ currentpagedevice pop copy
} bind def
(%currentgstatepagedevice) cvn
{ currentpagedevice pop currentgstate
} bind def
% Define interpreter callouts for handling gstate-restoring operators
% when the current page device needs to be changed.
% The names %grestorepagedevice, %grestoreallpagedevice,
% %restorepagedevice, and %setgstatepagedevice are known to the interpreter.
/.installpagedevice
{ % Since setpagedevice doesn't create new device objects,
% we must (carefully) reinstall the old parameters in
% the same device.
.currentpagedevice pop null currentdevice null .trysetparams
dup type /booleantype eq
{ pop pop }
{ % This should never happen!
DEBUG { (Error in .trysetparams!\n) print pstack flush } if
cleartomark pop pop pop
/.installpagedevice cvx /rangecheck signalerror
}
ifelse pop pop
erasepage initgraphics .beginpage
} bind def
/.uninstallpagedevice
{ 2 .endpage { .currentnumcopies false .outputpage } if
nulldevice
} bind def
(%grestorepagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice
} bind def
(%grestoreallpagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice grestoreall
} bind def
(%restorepagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice restore
} bind def
(%setgstatepagedevice) cvn
{ .uninstallpagedevice setgstate .installpagedevice
} bind def
% Redefine .currentnumcopies so it consults the NumCopies device parameter.
/.numcopiesdict mark
/NumCopies dup
.dicttomark readonly def
/.currentnumcopies
{ currentdevice //.numcopiesdict .getdeviceparams
dup type /integertype eq
{ exch pop exch pop }
{ cleartomark #copies }
ifelse
} bind odef
% ---------------- Auxiliary definitions ---------------- %
% Define the required attributes of all page devices, and their default values.
% We don't include attributes such as .MediaSize, which all devices
% are guaranteed to supply on their own.
/.defaultpolicies mark
/PolicyNotFound 1
/PageSize 0
/PolicyReport {pop} bind
.dicttomark readonly def
/.requiredattrs mark
/PageOffset [0 0] readonly
% We define InputAttributes and OutputAttributes with a single
% dummy media type that handles pages of any size.
% Devices that care will override this.
/InputAttributes mark 0
mark /PageSize [0 dup 16#7ffff dup] .dicttomark readonly
.dicttomark readonly
(%MediaSource) 0
/OutputAttributes mark 0
mark .dicttomark readonly
.dicttomark readonly
(%MediaDestination) 0
/Install {.callinstall} bind
/BeginPage {.callbeginpage} bind
/EndPage {.callendpage} bind
/Policies .defaultpolicies
.dicttomark readonly def
% Define currentpagedevice so it creates the dictionary on demand if needed,
% adding all the required entries defined just above.
% We have to deal specially with entries that the driver may change
% on its own.
/.dynamicppkeys mark
/.MediaSize dup % because it changes when PageSize is set
/PageCount dup
.dicttomark readonly def
/.makecurrentpagedevice % - .makecurrentpagedevice <dict>
{ currentdevice null .getdeviceparams
% In case of duplicate keys, .dicttomark takes the entry
% lower on the stack, so we can just append the defaults here.
.requiredattrs { } forall .dicttomark
dup .setpagedevice
} bind def
/currentpagedevice
{ .currentpagedevice
{ dup length 0 eq
{ pop .makecurrentpagedevice
}
{ % If any of the dynamic keys have changed,
% we must update the page device dictionary.
currentdevice //.dynamicppkeys .getdeviceparams .dicttomark
{ % Stack: current key value
2 index 2 index .knownget { 1 index ne } { true } ifelse
{ 2 index wcheck not
{ % This is the first entry being updated.
% Copy the dictionary to make it writable.
3 -1 roll dup length dict .copydict
3 1 roll
}
if
2 index 3 1 roll put
}
{ pop pop
}
ifelse
}
forall
% We would like to do a .setpagedevice so we don't keep
% re-creating the dictionary. Unfortunately, the effect
% of this is that if any dynamic key changes (PageCount
% in particular), we will do the equivalent of a
% setpagedevice at the next restore or grestore.
% Therefore, we make the dictionary read-only, but
% we don't store it away. I.e., NOT:
% dup wcheck { .setpagedevice .currentpagedevice pop } if
readonly
}
ifelse
}
if
} bind odef
% The implementation of setpagedevice is quite complex. Currently,
% everything but the media matching algorithm is implemented here.
% By default, we only present the requested changes to the device,
% but there are some parameters that require special merging action.
% Define those parameters here, with the procedures that do the merging.
% The procedures are called as follows:
% <merged> <key> <new_value> -proc- <merged> <key> <new_value'>
/.mergespecial mark
/InputAttributes
{ dup null eq
{ pop null
}
{ 3 copy pop .knownget
{ dup null eq
{ pop dup length dict }
{ dup length 2 index length add dict .copydict }
ifelse
}
{ dup length dict
}
ifelse .copydict readonly
}
ifelse
} bind
/OutputAttributes 1 index
/Policies
{ 3 copy pop .knownget
{ dup length 2 index length add dict .copydict }
{ dup length dict }
ifelse copy readonly
} bind
.dicttomark readonly def
% Define the keys used in input attribute matching.
/.inputattrk